package com.autoglm.android.core

import com.autoglm.android.core.db.AppKnowledgeBase
import com.autoglm.android.core.execution.CrossAppExecutionEngine
import com.autoglm.android.core.llm.LLMService
import com.autoglm.android.core.models.ExecutionResult
import com.autoglm.android.core.models.TaskExecutionPlan
import com.autoglm.android.core.models.UserIntent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.withContext

/**
 * 执行步骤处理状态
 */
sealed class CommandProcessingState {
    data class Initialized(val text: String) : CommandProcessingState()
    data class IntentRecognized(val intent: UserIntent) : CommandProcessingState()
    data class PlanGenerated(val plan: TaskExecutionPlan) : CommandProcessingState()
    data class Executing(val step: String, val progress: Int, val totalSteps: Int) : CommandProcessingState()
    data class Success(val result: ExecutionResult) : CommandProcessingState()
    data class Failed(val errorMessage: String) : CommandProcessingState()
    data class RequiresPermission(val permission: String) : CommandProcessingState()
}

/**
 * 语音命令处理器，将用户语音指令转化为实际操作
 */
class VoiceCommandProcessor(
    private val intentRecognizer: IntentRecognizer,
    private val taskPlanner: TaskPlanner,
    private val executionEngine: CrossAppExecutionEngine,
    private val appKnowledgeBase: AppKnowledgeBase,
    private val llmService: LLMService
) {
    /**
     * 处理语音命令，返回处理过程中的状态流
     * @param text 用户语音转文本输入
     * @return 状态流
     */
    fun processCommand(text: String): Flow<CommandProcessingState> = flow {
        emit(CommandProcessingState.Initialized(text))
        
        try {
            // 1. 识别用户意图
            val intent = intentRecognizer.recognizeIntent(text)
            emit(CommandProcessingState.IntentRecognized(intent))
            
            // 2. 生成执行计划
            val plan = taskPlanner.createExecutionPlan(intent)
            
            if (plan.steps.isEmpty()) {
                emit(CommandProcessingState.Failed("无法为该指令生成执行计划"))
                return@flow
            }
            
            emit(CommandProcessingState.PlanGenerated(plan))
            
            // 3. 检查权限
            for (permission in plan.requiredPermissions) {
                emit(CommandProcessingState.RequiresPermission(permission))
            }
            
            // 4. 执行任务计划
            val totalSteps = plan.steps.size
            var currentStep = 0
            
            for (step in plan.steps) {
                currentStep++
                emit(CommandProcessingState.Executing(
                    step = step.description,
                    progress = currentStep,
                    totalSteps = totalSteps
                ))
            }
            
            val result = executionEngine.executeTask(plan)
            
            // 5. 处理执行结果
            if (result.success) {
                // 更新应用操作知识
                appKnowledgeBase.updateOperationSuccess(
                    appName = intent.targetApp,
                    operation = intent.toDescriptiveString(),
                    executionSteps = plan.steps
                )
                
                emit(CommandProcessingState.Success(result))
            } else {
                emit(CommandProcessingState.Failed(result.errorMessage ?: "执行失败"))
            }
        } catch (e: Exception) {
            emit(CommandProcessingState.Failed("处理命令时出错: ${e.message}"))
        }
    }
    
    /**
     * 解释失败原因并提出改进建议
     * @param errorMessage 错误信息
     * @return 解释和建议
     */
    suspend fun explainFailureAndSuggest(errorMessage: String): String = withContext(Dispatchers.IO) {
        // 使用LLM解释错误并提出建议
        val prompt = """
            作为一个Android应用自动化助手，请分析以下任务执行失败的原因，并提供改进建议。
            错误信息: "$errorMessage"
            
            请提供:
            1. 可能的失败原因
            2. 用户可以尝试的不同表述或方法
            3. 一个具体的建议和改进的指令示例
            
            请用简洁自然的语言回答，就像在和用户对话一样。
        """.trimIndent()
        
        try {
            return@withContext llmService.generate(prompt, 0.7)
        } catch (e: Exception) {
            return@withContext "执行失败：$errorMessage。\n\n建议您尝试更明确的指令，或确认目标应用已安装并可访问。"
        }
    }
    
    /**
     * 获取任务执行总结
     * @param intent 用户意图
     * @param result 执行结果
     * @return 执行总结文本
     */
    suspend fun getSummary(intent: UserIntent, result: ExecutionResult): String = withContext(Dispatchers.IO) {
        val operationSummary = intent.toDescriptiveString()
        val duration = result.executionTimeMs / 1000.0
        
        return@withContext "成功执行了"$operationSummary"操作，耗时${duration}秒。"
    }
} 